import { CustomPage } from '/engine/index';
import {
  createConversation,
  getChatDetailById,
  sendMsg,
  sendMsgStream,
  getUnreadCount,
} from '../../services/chat';

const app = getApp();

CustomPage({
  data: {
    top: '',
    chatList: [],
    chatId: '',
    loading: false,
    bottom: 40,
    scrollTop: 0,
    showBack: false,
    article: {},
    userInfo: {},
    unreadCount: 0,
  },
  async onLoad(options) {
    if (options?.type === 'new') {
      this.setData({
        chatList: [],
        chatId: '',
        loading: false,
      });
    }
    if (options?.type === 'history') {
      const chatId = options?.chatId;
      const { rows } = await getChatDetailById(chatId);

      const list = rows?.map(item => {
        let content = item?.content;
        let type = item?.msgType;
        let isPdf = false;
        let role = item?.role;
        let name = '';
        let size = '';
        if (type === 'img') {
          content = item?.ossInfo?.[0]?.url;
        } else if (type === 'file') {
          ((isPdf = item?.ossInfo?.[0]?.originalName?.endsWith('pdf')),
            (name = item?.ossInfo?.[0]?.originalName));
          size = item?.ossInfo?.[0]?.fileSize;
        } else if (type === 'prescription') {
          try {
            content = JSON.parse(item?.content);
            role = 'assistant';
          } catch (e) {
            console.log(e);
          }
        } else {
          // TODO
          content = app.towxml(content, 'markdown');
          type = 'md';
        }
        return {
          role,
          content,
          type: type,
          isPdf,
          name,
          size,
        };
      });
      this.setData({ chatList: list, chatId, showBack: true });
    }

    const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
    const unreadCount = await getUnreadCount();

    this.setData({
      unreadCount: unreadCount?.data,
      top: menuButtonInfo.height + menuButtonInfo.top + 20,
    });
  },
  onOpenMore(event) {
    const content = event.detail;
    this.setData({ bottom: content });
  },
  changeLoadingStatus(status) {
    const { chatList } = this.data;
    if (status) {
      const newChatList = [...chatList];
      const loadingChat = {
        role: 'assistant',
        type: 'loading',
      };
      newChatList.push(loadingChat);
      this.setData({
        chatList: newChatList,
      });
    } else {
      const removeLoading = chatList.filter(chat => chat.type !== 'loading');
      this.setData({
        chatList: removeLoading,
      });
    }
    this.setData({ loading: status });
  },
  async onClickOptions(event) {
    const content = event.target.dataset.value;
    await this.sendMessage({ type: 'text', content, title: content });
  },
  async onSendTextMsg(event) {
    const content = event.detail;
    await this.sendMessage({ type: 'text', content, title: content });
  },
  async onSendFile(event) {
    const { file, type, name, size, isPdf, ossId, fileSession } = event.detail;

    await this.sendMessage({
      type,
      content: file,
      title: '图片',
      name,
      size,
      isPdf,
      ossId,
      fileSession,
    });
  },
  async sendMessage(message) {
    const { chatId, chatList, loading } = this.data;
    if (loading) {
      return;
    }
    // 如果没有 chatId，创建会话
    let newChatId = chatId;
    if (!newChatId) {
      const resp = await createConversation({ title: message.title });
      newChatId = resp?.data || '';
      if (!newChatId) throw new Error('创建会话失败');
      this.setData({ chatId: newChatId });
    }
    // 添加提示用户消息到聊天列表
    let updatedChatList = chatList || [];
    if (chatList.length < 1) {
      updatedChatList.unshift({
        role: 'assistant',
        content:
          '考虑用药安全，请确认账号登录为真实就诊人，为您推荐更合适的治疗建议。',
        type: 'text',
      });
    }
    const newUserMessage = { role: 'user', ...message };
    updatedChatList.push(newUserMessage);
    this.setData({
      chatList: [...updatedChatList],
    });
    this.scrollToBottom();
    this.changeLoadingStatus(true);

    // 发送消息
    const params =
      message.type === 'text'
        ? {
            conversationId: newChatId,
            content: message.content,
            msgType: 'text',
            role: 'user',
          }
        : {
            conversationId: newChatId,
            msgFile: message.fileSession,
            ossIds: message.ossId,
            msgType: message.type,
            role: 'user',
          };

    let options = [];
    let accumulatedText = '';
    let assistantMessageAdded = false;
    
    try {
      // 使用流式发送消息
      await sendMsgStream(
        params,
        (data) => {
          // 在第一次接收到数据时添加助手消息
          if (!assistantMessageAdded) {
            assistantMessageAdded = true;
            // 流式发送：添加一个助手消息（先以 text 占位，避免 towxml 空节点导致渲染异常）
            const assistantMessage = {
              role: 'assistant',
              content: '',
              type: 'md',
              options: options,
            };
            updatedChatList.push(assistantMessage);
            this.setData({
              chatList: updatedChatList,
            });

            // 保存最后一条助手消息索引用于定点更新
            this._streamAssistantIndex = updatedChatList.length - 1;
            this._streamAccumulatedText = '';
            if (this._streamMdTimer) {
              clearTimeout(this._streamMdTimer);
              this._streamMdTimer = null;
            }
          }
          
          accumulatedText = data;
          this._streamAccumulatedText = accumulatedText;
          // 节流：延迟少量时间再解析，避免高频 setData
          if (!this._streamMdTimer) {
            this._streamMdTimer = setTimeout(() => {
              this._streamMdTimer = null;
              const md = this._streamAccumulatedText || '';
              const idx = this._streamAssistantIndex;
              try {
                const parsedNodes = app.towxml(md, 'markdown');
                this.setData({
                  [`chatList[${idx}].type`]: 'md',
                  [`chatList[${idx}].content`]: parsedNodes,
                  [`chatList[${idx}].rawText`]: md,
                });
              } catch (err) {
                this.setData({
                  [`chatList[${idx}].type`]: 'text',
                  [`chatList[${idx}].content`]: this._streamAccumulatedText,
                  [`chatList[${idx}].rawText`]: md,
                });
                console.error('Markdown 解析失败:', err);
              }
              this.scrollToBottom();
            }, 10);
          }
        },
        (error) => {
          if (this._streamMdTimer) {
            clearTimeout(this._streamMdTimer);
            this._streamMdTimer = null;
          }
          // 只有在已添加助手消息的情况下才更新UI
          if (assistantMessageAdded) {
            this.changeLoadingStatus(false);
            wx.showToast({ title: '网络异常，请稍后再试', icon: 'none' });
          }
          console.error(error);
        },
        () => {
          // 最终一次刷新，确保完整 Markdown 被解析
          if (this._streamMdTimer) {
            clearTimeout(this._streamMdTimer);
            this._streamMdTimer = null;
          }
          // 只有在已添加助手消息的情况下才更新
          if (assistantMessageAdded) {
            try {
              const parsedNodes = app.towxml(this._streamAccumulatedText || '', 'markdown');
              const idx = this._streamAssistantIndex;
              this.setData({
                [`chatList[${idx}].type`]: 'md',
                [`chatList[${idx}].content`]: parsedNodes,
                [`chatList[${idx}].rawText`]: this._streamAccumulatedText || '',
              });
            } catch (err) {
              const idx = this._streamAssistantIndex;
              this.setData({
                [`chatList[${idx}].type`]: 'text',
                [`chatList[${idx}].content`]: this._streamAccumulatedText,
                [`chatList[${idx}].rawText`]: this._streamAccumulatedText || '',
              });
              console.error('Markdown 解析失败(完成阶段):', err);
            }
          }
          this.changeLoadingStatus(false);
          this.scrollToBottom();
        }
      );
    } catch (e) {
      if (this._streamMdTimer) {
        clearTimeout(this._streamMdTimer);
        this._streamMdTimer = null;
      }
      // 只有在已添加助手消息的情况下才更新UI
      if (assistantMessageAdded) {
        this.changeLoadingStatus(false);
        wx.showToast({ title: '网络异常，请稍后再试', icon: 'none' });
      }
      console.error(e);
    }
  },
  scrollToBottom() {
    const query = this.createSelectorQuery();

    // 获取所有 .speaker-warp 元素，用于计算总高度
    query
      .selectAll('.speaker-warp')
      .boundingClientRect(res => {
        if (res && res.length > 0) {
          const totalHeight = res.reduce((sum, item) => sum + item.height, 0);
          this.setData({
            scrollTop: totalHeight,
          });
        }
      })
      .exec();
  },
});
